package core;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;

public class OurGraphics {

	public static final int NO_DASH = 9999999;
	
	private BufferedImage mImage;
	
	private Graphics2D mGraphics2D;
	
	private int dashPhase = NO_DASH;
	
	private Clip mClip = new Clip();
 	
	public OurGraphics(BufferedImage img) {
		mImage = img;
		mGraphics2D = (Graphics2D) mImage.getGraphics();
	}
	
	public void setColor(Color c) {
		mGraphics2D.setColor(c);
	}
	
	public void setLinePattern(int fase) {
		dashPhase = fase;
	}
	
	public Clip getClip() {
		return mClip;
	}

	public void setClip(Clip clip) {
		this.mClip = clip;
	}

	public void clear() {
		mGraphics2D.setColor(Color.WHITE);
		mGraphics2D.fillRect(0, 0, mImage.getWidth(), mImage.getHeight());
	}
	
	public Graphics2D getRealGraphics() {
		return (Graphics2D) mGraphics2D;
	}
	
	public void drawSquare(Point3D p1, Point3D p2) {
		drawSquare(p1.getX(), p1.getY(), p2.getX(), p2.getY());
	}
	
	public void drawSquare(int x1, int y1, int x2, int y2) {
		drawLine(x1, y1, x2, y1);
		drawLine(x2, y1, x2, y2);
		drawLine(x1, y2, x2, y2);
		drawLine(x1, y1, x1, y2);
	}
	
	public void drawLine(int x1, int y1, int x2, int y2){
		
		xAcum = 0;
		linePatternOpaque = true;
		
		if(x1 > x2) {
			drawLine(x2, y2, x1, y1);
		}else if(y2 < y1){
			drawLine(x1, -1*y1, x2, -1*y2);
		}else if( Math.abs(y2 - y1) > Math.abs(x2 - x1) ) {
			drawLineY(x1, y1, x2, y2);
		}else {
			drawLineX(x1, y1, x2, y2);
		}
	}
	
	private void drawLineX(int x1, int y1, int x2, int y2){
		int x, y, s, dx, dy;
		
		y   = y1;
		dy  =   2*(y2 - y1);
		dx  = - 2*(x2 - x1);
		s   = dy-(x2-x1);
		
		for (x = x1; x <= x2; x++) {
			drawPoint(x, Math.abs(y));
			
			if (s > 0) {
		        s = s + dx + dy;
				y = y+1;
			}
			else {
				s = s + dy;
			}
		}
	}
	
	private void drawLineY(int x1, int y1, int x2, int y2) {
		int x, y, s, dx, dy;
		
		x   = x1;
		dx  =   2*(x2 - x1);
		dy  = - 2*(y2 - y1);
		s   = dx-(y2-y1);
		
		for (y = y1; y <= y2; y++) {
			drawPoint(x, Math.abs(y));
			
			if (s > 0) {
		        s = s + dy + dx;
				x = x+1;
			}
			else {
				s = s + dx;
			}
		}
	}
	
	private void drawPoint(int x, int y) {

		if(x >= mImage.getWidth() || y >= mImage.getHeight() ) {
			return;
		}

		try{
			if(linePatternOpaque) {
				mImage.setRGB(x,  Math.abs(y), mGraphics2D.getColor().getRGB());
			}
			
			if(xAcum > dashPhase) {
				xAcum = 0;
				linePatternOpaque = !linePatternOpaque;
			}
			xAcum++;
		}
		catch(Exception e) {
			System.out.printf("Size(%d,%d) - Point(%d,%d)\n", mImage.getWidth(),
					mImage.getHeight(), x, y);
		}
	}
	
	private boolean linePatternOpaque = true;
	
	private int xAcum = 0;

}
